/**
 * 网络请求拦截器 - 内容脚本
 * 负责在网页中拦截和监控网络请求
 */

/**
 * Extension 消息发送器
 * 通过自定义事件与 ISOLATED world 的 bridge.js 通信
 */
class ExtensionMessenger {
    constructor() {
        this.pendingRequests = new Map();
        this.requestIdCounter = 0;
        this.setupResponseListener();
    }

    /**
     * 设置响应监听器
     */
    setupResponseListener() {
        document.addEventListener('extension-response', (event) => {
            const {requestId, response} = event.detail;
            const pendingRequest = this.pendingRequests.get(requestId);

            if (pendingRequest) {
                clearTimeout(pendingRequest.timeout);
                this.pendingRequests.delete(requestId);
                pendingRequest.resolve(response);
            }
        });

        // 监听来自 background.js 的主动推送消息
        document.addEventListener('extension-push', (event) => {
            const {type, data} = event.detail;
            this.handlePushMessage(type, data);
        });
    }

    /**
     * 处理推送消息
     */
    handlePushMessage(type, data) {
        // 可以根据需要处理来自 background.js 的主动推送
        // console.log('[ExtensionMessenger] Received push message:', type, data);
    }

    /**
     * 发送消息给 background.js
     * @param {string} type - 消息类型
     * @param {Object} data - 消息数据
     * @param {boolean} needsResponse - 是否需要响应
     * @param {number} timeout - 超时时间（毫秒）
     * @returns {Promise} 响应Promise
     */
    sendMessage(type, data, needsResponse = false, timeout = 5000) {
        const requestId = `req_${++this.requestIdCounter}_${Date.now()}`;

        const event = new CustomEvent('extension-message', {
            detail: {
                requestId,
                type,
                data,
                needsResponse
            }
        });

        if (needsResponse) {
            return new Promise((resolve, reject) => {
                const timeoutId = setTimeout(() => {
                    this.pendingRequests.delete(requestId);
                    reject(new Error(`Message timeout: ${type}`));
                }, timeout);

                this.pendingRequests.set(requestId, {
                    resolve,
                    reject,
                    timeout: timeoutId
                });

                document.dispatchEvent(event);
            });
        } else {
            document.dispatchEvent(event);
            return Promise.resolve();
        }
    }
}

// 创建全局消息发送器实例
const extensionMessenger = new ExtensionMessenger();

/**
 * 发送扩展消息的便捷函数
 * @param {string} type - 消息类型
 * @param {Object} data - 消息数据
 * @param {boolean} needsResponse - 是否需要响应
 * @returns {Promise} 响应Promise
 */
function sendExtensionMessage(type, data, needsResponse = false,timeout) {
    return extensionMessenger.sendMessage(type, data, needsResponse,timeout);
}

class NetworkInterceptorContent {
    constructor() {
        this.originalFetch = window.fetch;
        this.originalXHROpen = XMLHttpRequest.prototype.open;
        this.originalXHRSend = XMLHttpRequest.prototype.send;

        this.init();
    }

    /**
     * 初始化内容脚本
     */
    init() {
        /*    this.interceptFetch();*/
        this.interceptXHR();
        this.setupMessageListener();
    }

    /**
     * 拦截Fetch API
     */
    interceptFetch() {
        /*const self = this;

        window.fetch = async function (input, init = {}) {

            const url = typeof input === 'string' ? input : input.url;
            const method = init.method || 'GET';

            // 检查是否需要拦截
            const shouldIntercept = await self.shouldInterceptRequest(url);
            if (!shouldIntercept) {
                return self.originalFetch.apply(this, arguments);
            }

            // 检查Mock规则
            const mockResponse = await self.checkMockRules(url, method, init);
            if (mockResponse) {
                console.log('Fetch请求被Mock拦截:', url);
                return mockResponse;
            }

            // 记录请求信息
            const requestInfo = {
                url: url,
                method: method,
                headers: init.headers || {},
                body: init.body || null,
                timestamp: Date.now()
            };

            try {
                // 执行原始请求
                const response = await self.originalFetch.apply(this, arguments);

                // 记录响应信息
                const responseInfo = {
                    status: response.status,
                    statusText: response.statusText,
                    headers: self.headersToObject(response.headers),
                    url: response.url
                };

                // 克隆响应以获取响应体
                const clonedResponse = response.clone();
                try {
                    const responseText = await clonedResponse.text();
                    responseInfo.body = responseText;
                } catch (error) {
                    responseInfo.body = '';
                }

                // 发送请求信息到后台
                self.sendRequestInfo(requestInfo, responseInfo);

                return response;
            } catch (error) {
                // 记录错误信息
                const errorInfo = {
                    status: 0,
                    statusText: error.message,
                    headers: {},
                    body: error.toString()
                };

                self.sendRequestInfo(requestInfo, errorInfo);
                throw error;
            }
        };*/
    }

    /**
     * 拦截XMLHttpRequest
     */
    interceptXHR() {
        const self = this;

        // 拦截open方法
        XMLHttpRequest.prototype.open = function (method, url, async, user, password) {
            this._interceptorData = {
                method: method,
                url: url,
                requestHeaders: {},
                timestamp: Date.now()
            };

            return self.originalXHROpen.apply(this, arguments);
        };

        // 拦截send方法
        XMLHttpRequest.prototype.send = async function (body) {
            if (!this._interceptorData) {
                return self.originalXHRSend.apply(this, arguments);
            }

            const url = this._interceptorData.url;
            const method = this._interceptorData.method;


            // 检查是否需要存在 在webList
            const shouldIntercept = await self.shouldInterceptRequest(url);
            console.log('东西是否在weblist中', shouldIntercept);

            // 处理并保存请求体 (payload)
            this._interceptorData.body = self.processRequestBody(body);

            if (shouldIntercept) {
                const mockResponse = await self.checkMockRules(url, method, {body});
                console.log('找到拦截配置：', mockResponse);
                if (mockResponse) {
                    console.log('开始重写 返回内容 直接使用mock的数据返回', `
                    url:${url},
                    request-payload:${ JSON.stringify(  this._interceptorData.body) }`);

                    // 模拟XHR响应
                    setTimeout(() => {
                        Object.defineProperty(this, 'readyState', {value: 4, writable: false});
                        Object.defineProperty(this, 'status', {value: mockResponse.status, writable: false});
                        Object.defineProperty(this, 'statusText', {value: mockResponse.statusText, writable: false});
                        Object.defineProperty(this, 'responseText', {
                            value: mockResponse.responseText,
                            writable: false
                        });
                        Object.defineProperty(this, 'response', {value: mockResponse.response, writable: false});
                        if (this.onreadystatechange) {
                            this.onreadystatechange();
                        }

                        if (this.onload) {
                            this.onload();
                        }
                        if (this.onloadend) {
                            this.onloadend();
                        }
                    }, mockResponse?.delay || 0);

                    return;
                }
            }




            // 监听状态变化
            const originalOnReadyStateChange = this.onreadystatechange;
            this.onreadystatechange = function () {
                if (this.readyState === 4) {
                    // 请求完成，使用增强的响应体获取方法
                    const handleResponseBody = (responseBody) => {
                        const responseInfo = {
                            status: this.status,
                            statusText: this.statusText,
                            headers: self.parseResponseHeaders(this.getAllResponseHeaders()),
                            body: responseBody
                        };

                        self.sendRequestInfo(this._interceptorData, responseInfo);
                    };

                    // 使用增强的响应体获取方法
                    const responseBody = self.getEnhancedResponseBody(this, handleResponseBody);

                    // 对于同步返回的响应体（非blob类型），立即处理
                    if (responseBody !== undefined) {
                        handleResponseBody(responseBody);
                    }
                    // 对于异步处理的响应体（blob类型），会通过callback处理
                }

                if (originalOnReadyStateChange) {
                    originalOnReadyStateChange.apply(this, arguments);
                }
            };

            return self.originalXHRSend.apply(this, arguments);
        };

        // 拦截setRequestHeader方法
        const originalSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
        XMLHttpRequest.prototype.setRequestHeader = function (name, value) {
            if (this._interceptorData) {
                this._interceptorData.requestHeaders[name] = value;
            }
            return originalSetRequestHeader.apply(this, arguments);
        };
    }

    //  处理payload 请求
    processRequestBody(body) {
        if (!body) {
            return null;
        }

        try {
            // 处理FormData类型
            if (body instanceof FormData) {
                const formDataObj = {};
                for (const [key, value] of body.entries()) {
                    formDataObj[key] = value;
                }
                return {
                    type: 'formdata',
                    content: formDataObj
                };
            }

            // 处理Blob类型
            if (body instanceof Blob) {
                return {
                    type: 'blob',
                    size: body.size,
                    type: body.type
                    // 注意：Blob内容无法直接获取，需要使用FileReader
                    // 如果确实需要内容，可以添加异步读取逻辑
                };
            }

            // 处理ArrayBuffer或TypedArray
            if (body instanceof ArrayBuffer ||
                ArrayBuffer.isView(body)) {
                return {
                    type: 'binary',
                    size: body.byteLength
                };
            }

            // 处理URLSearchParams
            if (body instanceof URLSearchParams) {
                const paramsObj = {};
                for (const [key, value] of body.entries()) {
                    paramsObj[key] = value;
                }
                return {
                    type: 'urlencoded',
                    content: paramsObj
                };
            }

            // 处理JSON字符串
            if (typeof body === 'string') {
                try {
                    const jsonObj = JSON.parse(body);
                    return {
                        type: 'json',
                        content: jsonObj
                    };
                } catch (e) {
                    // 不是有效的JSON，作为普通文本处理
                    return {
                        type: 'text',
                        content: body
                    };
                }
            }

            // 处理其他对象类型
            if (typeof body === 'object') {
                return {
                    type: 'object',
                    content: body
                };
            }

            // 默认情况
            return {
                type: 'unknown',
                content: String(body)
            };

        } catch (error) {
            console.error('Error processing request body:', error);
            return {
                type: 'error',
                error: error.message,
                originalBody: body
            };
        }
    }


    /**
     * 检查是否应该拦截请求
     */
    async shouldInterceptRequest(url) {
        try {
            const response = await sendExtensionMessage('SHOULD_INTERCEPT', {url: url}, true);
            return response && response.shouldIntercept;
        } catch (error) {
            console.warn('[shouldInterceptRequest] Failed to check intercept rules:', error);
            return false;
        }
    }

    /**
     * 检查Mock规则
     */
    async checkMockRules(url, method, options) {
        try {
            const response = await sendExtensionMessage('CHECK_MOCK_RULES', {
                url: url,
                method: method,
                options: options
            }, true,500);
            // console.log('是否有拦截mock',url,response);
            if (response && response.mockRule) {
                const mockRule = response.mockRule;

                // 创建Mock响应
                if (window.fetch && options.headers) {
                    // Fetch API响应
                    const mockResponseText = JSON.stringify(mockRule.mockJson);
                    return new Response(mockResponseText, {
                        status: mockRule.statusCode || 200,
                        statusText: 'OK',
                        headers: {
                            'Content-Type': 'application/json',
                            'Access-Control-Allow-Origin': '*'
                        }
                    });
                } else {
                    // XHR响应
                    return {
                        status: mockRule.statusCode || 200,
                        statusText: 'OK',
                        responseText: mockRule.response,
                        response: JSON.parse(mockRule?.response),
                        delay: mockRule.delay || 0
                    };
                }
            }
        } catch (error) {
            console.error('检查Mock规则失败:', error);
        }

        return null;
    }

    /**
     * 发送请求信息到后台
     */
    sendRequestInfo(requestInfo, responseInfo) {
        const fullRequestInfo = {
            id: this.generateId(),
            method: requestInfo.method,
            url: requestInfo.url,
            requestBody: this.formatRequestBody(requestInfo.body),
            requestParams: this.extractRequestParams(requestInfo.url),
            requestHeaders: requestInfo.requestHeaders || requestInfo.headers || {},
            responseCode: responseInfo.status,
            responseBody: responseInfo.body || '',
            timestamp: requestInfo.timestamp,
            isMocked: false
        };

        sendExtensionMessage('RECORD_REQUEST', {request: fullRequestInfo}, false)
            .catch((error) => {
                console.warn('[sendRequestInfo] Failed to record request:', error);
            });
    }

    /**
     * 格式化请求体
     */
    formatRequestBody(body) {
        if (!body) return '';

        if (typeof body === 'string') {
            return body;
        }

        if (body instanceof FormData) {
            const formDataObj = {};
            for (let [key, value] of body.entries()) {
                formDataObj[key] = value;
            }
            return JSON.stringify(formDataObj);
        }

        if (body instanceof URLSearchParams) {
            return body.toString();
        }

        try {
            return JSON.stringify(body);
        } catch (error) {
            return body.toString();
        }
    }

    /**
     * 提取请求参数
     */
    extractRequestParams(url) {
        try {
            const urlObj = new URL(url);
            return urlObj.search;
        } catch (error) {
            return '';
        }
    }

    /**
     * 将Headers对象转换为普通对象
     */
    headersToObject(headers) {
        const result = {};
        if (headers && headers.forEach) {
            headers.forEach((value, key) => {
                result[key] = value;
            });
        }
        return result;
    }

    /**
     * 解析响应头字符串
     */
    parseResponseHeaders(headerStr) {
        const headers = {};
        if (!headerStr) return headers;

        const headerPairs = headerStr.trim().split('\r\n');
        headerPairs.forEach(line => {
            const parts = line.split(': ');
            if (parts.length === 2) {
                headers[parts[0]] = parts[1];
            }
        });

        return headers;
    }

    /**
     * 根据responseType获取增强的响应体数据
     * @param {XMLHttpRequest} xhr - XHR对象
     * @param {Function} callback - 异步回调函数，用于处理异步响应体获取
     * @returns {string|Promise} 响应体数据或Promise（对于异步处理）
     */
    getEnhancedResponseBody(xhr, callback) {
        try {
            const responseType = xhr.responseType || '';

            switch (responseType) {
                case '':
                case 'text':
                    // 默认文本类型，使用responseText
                    const textResponse = xhr.responseText || '';
                    if (callback) callback(textResponse);
                    return textResponse;

                case 'json':
                    // JSON类型，序列化response对象
                    try {
                        const jsonResponse = xhr.response ? JSON.stringify(xhr.response) : '';
                        if (callback) callback(jsonResponse);
                        return jsonResponse;
                    } catch (error) {
                        console.warn('JSON响应序列化失败:', error);
                        const fallbackResponse = xhr.responseText || '';
                        if (callback) callback(fallbackResponse);
                        return fallbackResponse;
                    }

                case 'blob':
                    // Blob类型，需要异步读取
                    if (xhr.response && xhr.response instanceof Blob) {
                        const reader = new FileReader();
                        reader.onload = () => {
                            const blobResponse = reader.result || '';
                            if (callback) callback(blobResponse);
                        };
                        reader.onerror = () => {
                            console.warn('Blob读取失败');
                            if (callback) callback('');
                        };
                        reader.readAsText(xhr.response);
                        return; // 异步处理，不返回值
                    } else {
                        const emptyResponse = '';
                        if (callback) callback(emptyResponse);
                        return emptyResponse;
                    }

                case 'arraybuffer':
                    // ArrayBuffer类型，使用TextDecoder解码
                    if (xhr.response && xhr.response instanceof ArrayBuffer) {
                        try {
                            const decoder = new TextDecoder('utf-8');
                            const bufferResponse = decoder.decode(xhr.response);
                            if (callback) callback(bufferResponse);
                            return bufferResponse;
                        } catch (error) {
                            console.warn('ArrayBuffer解码失败:', error);
                            const fallbackResponse = '';
                            if (callback) callback(fallbackResponse);
                            return fallbackResponse;
                        }
                    } else {
                        const emptyResponse = '';
                        if (callback) callback(emptyResponse);
                        return emptyResponse;
                    }

                case 'document':
                    // Document类型，获取HTML内容
                    if (xhr.response && xhr.response.documentElement) {
                        const docResponse = xhr.response.documentElement.outerHTML || '';
                        if (callback) callback(docResponse);
                        return docResponse;
                    } else {
                        const fallbackResponse = xhr.responseText || '';
                        if (callback) callback(fallbackResponse);
                        return fallbackResponse;
                    }

                default:
                    // 未知类型，降级到responseText
                    console.warn('未知的responseType:', responseType);
                    const defaultResponse = xhr.responseText || '';
                    if (callback) callback(defaultResponse);
                    return defaultResponse;
            }
        } catch (error) {
            console.error('获取增强响应体失败:', error);
            // 降级方案：使用原始的responseText
            const fallbackResponse = xhr.responseText || '';
            if (callback) callback(fallbackResponse);
            return fallbackResponse;
        }
    }

    /**
     * 设置消息监听器
     */
    setupMessageListener() {
        // 通过 ExtensionMessenger 处理来自 background.js 的推送消息
        const originalHandlePushMessage = extensionMessenger.handlePushMessage;
        extensionMessenger.handlePushMessage = (type, data) => {
            // 调用原始处理函数
            originalHandlePushMessage.call(extensionMessenger, type, data);

            // 处理特定的消息类型
            this.handleMessage({type, ...data}, null, null);
        };
    }

    /**
     * 处理来自后台的消息
     */
    handleMessage(message, sender, sendResponse) {
        switch (message.type) {
            /* case 'GET_PAGE_REQUESTS':
               // 获取页面请求信息
               sendResponse({ requests: this.getPageRequests() });
               break;*/


            default:
                sendResponse({error: 'Unknown message type'});
        }
    }

    /**
     * 获取页面请求信息
     */
    getPageRequests() {
        // 这里可以返回页面级别的请求信息
        return [];
    }

    /**
     * 注入Mock脚本
     */
    injectMockScript(mockRules) {
        // 可以根据需要注入额外的Mock脚本
        console.log('注入Mock脚本:', mockRules);
    }

    /**
     * 生成唯一ID
     */
    generateId() {
        return Date.now().toString(36) + Math.random().toString(36).substr(2);
    }
}

// 只在主框架中初始化
if (window === window.top) {
    const contentScript = new NetworkInterceptorContent();
}

// 监听页面卸载事件
window.addEventListener('beforeunload', () => {
    console.log('【beforeunload】');
});